#include <QThread>
#include <QList>
#include <QTextDecoder>
#include <QJsonDocument>
#include <QJsonObject>
#include "serviceprovider.h"

#define HTTP_DEBUG

ServiceProvider::ContentParameter::ContentParameter():
    key(""),
    value(""),
    hash_key("")
{
}

ServiceProvider::ContentParameter::ContentParameter(QString _key, QString _value, QString _hash_key):
    key(_key),
    value(_value),
    hash_key(_hash_key)
{
}

ServiceProvider::ContentParameter& ServiceProvider::ContentParameter::operator=(const ContentParameter &other)
{
    key=other.key;
    value=other.value;
    hash_key=other.hash_key;
    return *this;
}

bool ServiceProvider::ContentParameter::operator==(const ContentParameter &other)
{
    if((key==other.key)&&(value==other.value)&&(hash_key==other.hash_key)) return true;
    else return false;
}

ServiceProvider::OperationContent::OperationContent():
    address(""),
    method(NONE),
    errorStrings(QStringList("Error")),
    ReceiveParamenters(QList<ContentParameter>()),
    SendParamenters(QList<ContentParameter>())
{
}

ServiceProvider::OperationContent::OperationContent(Method _method, QString _address, int _percent_completed,
                                                   QList<ContentParameter> _ReceiveParamenters,
                                                   QList<ContentParameter> _SendParamenters, QStringList _errorStrings, QString _errorMessage,
                                                   ContentAnswerType _answerType,
                                                   ContentRequstType _requestType,
                                                   void (*_func)()):
    address(_address),
    method(_method),
    errorStrings(_errorStrings),
    errorMsg(_errorMessage),
    ReceiveParamenters(_ReceiveParamenters),
    SendParamenters(_SendParamenters),
    answerType(_answerType),
    requestType(_requestType),
    percent_completed(_percent_completed),
    func(_func)
{
}

ServiceProvider::OperationContent& ServiceProvider::OperationContent::operator=(const OperationContent &other)
{
    address=other.address;
    method=other.method;
    errorStrings=other.errorStrings;
    ReceiveParamenters.clear();
    ReceiveParamenters=other.ReceiveParamenters;
    SendParamenters.clear();
    SendParamenters=other.SendParamenters;
    return *this;
}

bool ServiceProvider::OperationContent::operator==(const OperationContent &other)
{
    if((!address.compare(other.address))&&
       (method==other.method)&&
       (errorStrings == other.errorStrings)&&
       (ReceiveParamenters==other.ReceiveParamenters)&&
       (SendParamenters==other.SendParamenters))
        return true;
    else
        return false;
}


ServiceProvider::ServiceProvider(QObject *parent) :
    QObject(parent),
    m_currentOperation(0),
    m_finishedOperation(true)
{
    connect(this, SIGNAL(OperFinished()), this, SLOT(finishedOper()));
    connect(this, SIGNAL(OperFinished()), &m_loop, SLOT(quit()));
}

ServiceProvider::ServiceProvider(QList<OperationContent> *operList, QObject *parent):
    QObject(parent),
    m_operList(operList),
    m_currentOperation(0),
    m_finishedOperation(true)
{
    connect(this, SIGNAL(OperFinished()), this, SLOT(finishedOper()));
    connect(this, SIGNAL(OperFinished()), &m_loop, SLOT(quit()));
}

ServiceProvider::~ServiceProvider()
{
}


void ServiceProvider::Start()
{
    CreateList();
    if(m_operList) m_manager=new QNetworkAccessManager;
    Engine();
}


void ServiceProvider::Encrypted()
{
    qDebug()<<"Encrypted";
    emit OperFinished();
    //finishedOper();
}

void ServiceProvider::SslSocketError(QList<QSslError> err_list)
{
    qDebug()<<"SSL Socket Errors";
}

void ServiceProvider::socketError(QAbstractSocket::SocketError)
{
    qDebug()<<"socketError: "<<this_socket->errorString();
    m_currentOperation=m_operList->size();
    emit OperationError(this_socket->errorString());
    //QString *warn= new QString(socket->errorString());
    //emit warning(QString(socket->errorString()));
}

void ServiceProvider::socketReadyRead()
{
    qDebug()<<"ReadyRead";
}

void ServiceProvider::sslErrorsSlot(QNetworkReply*reply, QList<QSslError> errList)
{
   qDebug()<<"sslErrorsSlot:";
   for(int i=0;i<errList.size();i++)
       qDebug()<<errList.at(i);
}


void ServiceProvider::Engine()
{
    //DoCONNECT();
//    while(m_currentOperation<m_operList->size())
//    {
        if(m_finishedOperation)
        {
            m_finishedOperation=false;
            switch(m_operList->at(m_currentOperation).method)
            {
            case CONNECT:
                    DoCONNECT();
                break;
            case GET:
                    DoGET();
                break;
            case POST:
                    DoPOST();
                break;
            case CLOSE:
                    DoCLOSE();
                break;
            };
        }
//        m_currentOperation++;

        //m_loop.exec();
//    }

}

void ServiceProvider::DoCONNECT()
{
    QString address=TakeAddress(m_operList->at(m_currentOperation).address);
    qDebug()<<"SslOperation::DoCONNECT to "<<address;
    this_socket =  new QSslSocket;

    connect(this_socket, SIGNAL(encrypted()), this, SLOT(Encrypted()));
    connect(this_socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(this_socket, SIGNAL(sslErrors(QList<QSslError>)),
            this, SLOT(SslSocketError(QList<QSslError>)));

//    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
//                     this, SLOT(finishedGetRequestSlot(QNetworkReply*)));

//    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
//                     this, SLOT(finishedGetRequestSlot2(QNetworkReply*)));

//    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
//                     this, SLOT(finishedPostRequestSlot(QNetworkReply*)));

    m_protocol=QSsl::TlsV1_0;
    this_socket->setProtocol(m_protocol);
    this_socket->setSocketOption(QAbstractSocket::KeepAliveOption,1);

    this_socket->connectToHostEncrypted(address, 443);

//    //m_manager = new QNetworkAccessManager;
//    QNetworkAccessManager *manager = new QNetworkAccessManager;

//    connect(manager, SIGNAL(encrypted(QNetworkReply*)),
//             this, SLOT(Encrypted(QNetworkReply*)));
//    connect(manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
//            this, SLOT(sslErrorsSlot(QNetworkReply*,QList<QSslError>)));

//    QUrl url(TakeAddress(m_operList->at(m_currentOperation).address));
//    QNetworkRequest request;
//    QSslConfiguration ssl_config;
//    ssl_config.setProtocol(m_protocol);
//    request.setSslConfiguration(ssl_config);
//    request.setUrl(url);

//    //m_manager.moveToThread(this->thread());
//    manager->connectToHostEncrypted(TakeAddress(m_operList->at(m_currentOperation).address));
//    //m_manager.moveToThread(this->thread());
}

void ServiceProvider::DoGET()
{
    //QNetworkAccessManager *manager = new QNetworkAccessManager;

    connect(m_manager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(finishedGetRequestSlot(QNetworkReply*)));
    connect(m_manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
            this, SLOT(sslErrorsSlot(QNetworkReply*,QList<QSslError>)));

    QUrl url(TakeAddress(m_operList->at(m_currentOperation).address));
    QNetworkRequest request;
    QSslConfiguration ssl_config;
    ssl_config.setProtocol(m_protocol);
    request.setSslConfiguration(ssl_config);
    request.setUrl(url);

    qDebug()<<"GET to "<<request.url().toString();
    m_manager->get(request);
}

void ServiceProvider::DoPOST()
{

    QNetworkRequest request;
    QSslConfiguration ssl_config;
    //QNetworkAccessManager *manager = new QNetworkAccessManager;
    ssl_config.setProtocol(m_protocol);
    request.setSslConfiguration(ssl_config);
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
    request.setUrl(TakeAddress(m_operList->at(m_currentOperation).address));

    connect(m_manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
            this, SLOT(sslErrorsSlot(QNetworkReply*,QList<QSslError>)));
    connect(m_manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(finishedPostRequestSlot(QNetworkReply*)));

    QString value;
    if(m_operList->at(m_currentOperation).requestType==PercentEncoding)
    {
        QByteArray postData;
        QString key;
        int index=0;
        int index2=0;

        index=m_operList->at(m_currentOperation).SendParamenters.at(0).key.indexOf("<<");
        if(index==-1)
            key=m_operList->at(m_currentOperation).SendParamenters.at(0).key.toUtf8();
        else
        {
            index2=m_operList->at(m_currentOperation).SendParamenters.at(0).key.indexOf(">>");
            if(index2==-1) emit Error("Error in syntax");

            key=m_hash[m_operList->at(m_currentOperation).SendParamenters.at(0).key.toUtf8().mid(index+2,index2-index-2)];
        }

        if(m_operList->at(m_currentOperation).SendParamenters.at(0).value=="")
        {
            value=m_hash[key];
        }
        else
        {
            value=m_operList->at(m_currentOperation).SendParamenters.at(0).value;
        }

        postData.append(key+"="+QUrl::toPercentEncoding(value.toUtf8()));


        for(int i=1;i<m_operList->at(m_currentOperation).SendParamenters.size();i++)
        {

            index=m_operList->at(m_currentOperation).SendParamenters.at(i).key.indexOf("<<");
            if(index==-1)
                key=m_operList->at(m_currentOperation).SendParamenters.at(i).key.toUtf8();
            else
            {
                index2=m_operList->at(m_currentOperation).SendParamenters.at(i).key.indexOf(">>");
                if(index2==-1) emit Error("Error in syntax");

                key=m_hash[m_operList->at(m_currentOperation).SendParamenters.at(i).key.toUtf8().mid(index+2,index2-index-2)];
            }

            if(m_operList->at(m_currentOperation).SendParamenters.at(i).value=="")
            {
                value=m_hash[key];
            }
            else
            {
                value=m_operList->at(m_currentOperation).SendParamenters.at(i).value;
            }

            postData.append("&"+(key+"="+QUrl::toPercentEncoding(value.toUtf8())));
        }
        qDebug()<<"postData: "<<postData;
        qDebug()<<"POST to "<<request.url().toString();
        m_manager->post(request, QString(postData).toUtf8());
    }
    else if(m_operList->at(m_currentOperation).requestType==JSONRequest)//!!
    {
        QJsonDocument *jsonRequest=new QJsonDocument;
        QJsonObject jsonObj;
        for(int i=0;i<m_operList->at(m_currentOperation).SendParamenters.size();i++)
        {
           if(m_operList->at(m_currentOperation).SendParamenters.at(i).value=="")
               value=m_hash[m_operList->at(m_currentOperation).SendParamenters.at(i).hash_key];
           else
               value=m_operList->at(m_currentOperation).SendParamenters.at(i).value;
           jsonObj[m_operList->at(m_currentOperation).SendParamenters.at(i).key]=value;
           jsonRequest->setObject(jsonObj);
        }
        QByteArray postData=jsonRequest->toJson(QJsonDocument::Compact);
        qDebug()<<"postData: "<<postData;
        qDebug()<<"POST to "<<request.url().toString();
        m_manager->post(request, QString(postData).toUtf8());
    }
}

void ServiceProvider::DoCLOSE()
{
    this_socket->close();
    emit OperFinished();
    //finishedOper();
}

void ServiceProvider::SetOperList(QList<OperationContent> *operList)
{
    m_operList=operList;
}

int ServiceProvider::getUserParameter()
{
   return m_userParameter;
}

//void ServiceProvider::DoOperation()
//{
//    qDebug()<<"DoOperation";
//}

void ServiceProvider::Error(QString error)
{
    qDebug()<<"ServiceProvider::socketError: "<<error;
    m_currentOperation=m_operList->size();
    emit OperationError(error);
}

void ServiceProvider::Errors(QList<QSslError> err_list)
{
    m_currentOperation=m_operList->size();
    emit OperationErrors(err_list);
}

void ServiceProvider::OperProcessing()
{
}

QString ServiceProvider::Message4SmsCodeWindow()
{
    return "Payment||accaunt||credit card||\
           CC number||amount||amount value||\
           please enter received sms-code";
}

void ServiceProvider::finishedGetRequestSlot(QNetworkReply* reply)
{
    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedGetRequestSlot(QNetworkReply*)));

    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = reply->readAll();  // bytes
        qDebug()<<"\n\nfinishedGETRequestSlot";
        #ifdef HTTP_DEBUG
        //QTextCodec* defaultTextCodec = QTextCodec::codecForHtml(bytes);
        QTextCodec* defaultTextCodec = QTextCodec::codecForName("CP-1251");
        QTextDecoder *decoder = new QTextDecoder(defaultTextCodec);
        QString str = decoder->toUnicode(bytes);
        qDebug()<<"from :"<<reply->header(QNetworkRequest::LocationHeader).toString()<< "\n"<<str;
        #endif

        QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        if((statusCodeV==301)||(statusCodeV==302))
        {
            QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
            qDebug()<<"redirectionTargetUrl="<<QString(redirectionTargetUrl.toString());
            QUrl url(redirectionTargetUrl.toString());
            QNetworkRequest request;
            QSslConfiguration ssl_config;
            ssl_config.setProtocol(m_protocol);
            request.setSslConfiguration(ssl_config);
            request.setUrl(url);

            //m_manager=new QNetworkAccessManager;
            QObject::connect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedGetRequestSlot2(QNetworkReply*)));
            qDebug()<<"GET to "<<request.url().toString();
            m_manager->get(request);
        }
        else
        {
            qDebug()<<"parsing host answer from GET...";
            ParseAnswer(bytes);
            //finishedOper();
            //emit OperFinished();
        }
    }
    else
    {// Some http error received
        qDebug()<<"Get replyError: " << reply->error()<<": "<<reply->errorString();
        emit Error(reply->errorString());
    }
}

void ServiceProvider::finishedGetRequestSlot2(QNetworkReply* reply)
{
    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedGetRequestSlot2(QNetworkReply*)));

    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = reply->readAll();  // bytes
        qDebug()<<"\n\nfinishedGETRequestSlot";
        #ifdef HTTP_DEBUG
        //QTextCodec* defaultTextCodec = QTextCodec::codecForHtml(bytes);
        QTextCodec* defaultTextCodec = QTextCodec::codecForName("CP-1251");
        QTextDecoder *decoder = new QTextDecoder(defaultTextCodec);
        QString str = decoder->toUnicode(bytes);
        qDebug()<<"from :"<<reply->header(QNetworkRequest::LocationHeader).toString()<< "\n"<<str;
        #endif

        QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        if((statusCodeV==301)||(statusCodeV==302))
        {
            QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
            qDebug()<<"redirectionTargetUrl="<<QString(redirectionTargetUrl.toString());
            QUrl url(redirectionTargetUrl.toString());
            QNetworkRequest request;
            QSslConfiguration ssl_config;
            ssl_config.setProtocol(m_protocol);
            request.setSslConfiguration(ssl_config);
            request.setUrl(url);

            //m_manager=new QNetworkAccessManager;
            QObject::connect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedGetRequestSlot(QNetworkReply*)));
            qDebug()<<"GET to "<<request.url().toString();
            m_manager->get(request);
        }
        else
        {
            qDebug()<<"parsing host answer from GET2...";
            ParseAnswer(bytes);
            //finishedOper();
            //emit OperFinished();
        }
    }
    else
    {// Some http error received
        qDebug()<<"Get replyError: " << reply->error()<<": "<<reply->errorString();
        emit Error(reply->errorString());
    }
}

void ServiceProvider::finishedPostRequestSlot(QNetworkReply *reply)
{
    QObject::disconnect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedPostRequestSlot(QNetworkReply*)));
    // no error received?
    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray replyBa=reply->readAll();

        #ifdef HTTP_DEBUG
        //QTextCodec* defaultTextCodec = QTextCodec::codecForHtml(replyBa);
        QTextCodec* defaultTextCodec = QTextCodec::codecForName("CP-1251");
        QTextDecoder *decoder = new QTextDecoder(defaultTextCodec);
        QString str = decoder->toUnicode(replyBa);
        qDebug()<<"\n\nfinishedPOSTRequestSlot from :"<<reply->header(QNetworkRequest::LocationHeader).toString()<< "\n"<<str;
        #endif

        QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        if((statusCodeV==301)||(statusCodeV==302))
        {
            QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
            qDebug()<<"redirectionTargetUrl="<<QString(redirectionTargetUrl.toString());
            QUrl url(redirectionTargetUrl.toString());
            QNetworkRequest request;
            QSslConfiguration ssl_config;
            ssl_config.setProtocol(m_protocol);
            request.setSslConfiguration(ssl_config);
            request.setUrl(url);
            //m_manager=new QNetworkAccessManager;
            connect(m_manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
                    this, SLOT(sslErrorsSlot(QNetworkReply*,QList<QSslError>)));
            connect(m_manager, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(finishedGetRequestSlot(QNetworkReply*)));
            connect(this, SIGNAL(OperFinished()), this, SLOT(finishedOper()));

            qDebug()<<"GET to "<<request.url().toString();
            m_manager->get(request);
        }
        else
        {
            qDebug()<<"parsing host answer from POST...";
            ParseAnswer(replyBa);
            //finishedOper();
            //emit OperFinished();
        }
    }
    // Some http error received
    else
    {
        qDebug()<<"Post replyError: "<<reply->errorString();
        emit Error(reply->errorString());
    }

    reply->deleteLater();
}

void ServiceProvider::SetPassword(QString passw)
{
}

void ServiceProvider::SetMobileNumber(QString phone)
{
}

void ServiceProvider::OperationIncrement()
{
   m_currentOperation++;
}

void ServiceProvider::finishedOper()
{
    emit(PercentFinished(m_operList->at(m_currentOperation).percent_completed));
    OperProcessing();

    //m_currentOperation++;
    qDebug()<<"===m_currentOperation="<<m_currentOperation;
    m_finishedOperation=true;

    if(m_currentOperation+1>=m_operList->size())
    {
        qDebug()<<"Session has been finished.";
        if(!m_hash["SessionResult"].isEmpty())
           emit OperationFinished(m_hash["SessionResult"]);
        else
           emit OperationError("Error in final stage");
    }
    else
    {
        m_currentOperation++;
        //emit(OperationIncrement());
        Engine();
    }

}

void ServiceProvider::ParseAnswer(QByteArray &bytes)
{
    int valid_results=0;
    bool    errorFound=false;
    QList<ContentParameter> *recParam=(QList<ContentParameter> *)&(m_operList->at(m_currentOperation).ReceiveParamenters);
    if(m_operList->at(m_currentOperation).answerType==HTML)
    {
        QString ReplyStr(bytes); // string

        QTextCodec* defaultTextCodec = QTextCodec::codecForName("CP-1251");
        QTextDecoder *decoder = new QTextDecoder(defaultTextCodec);
        QString str = decoder->toUnicode(bytes);

        //searching error
        for(int i=0;i<m_operList->at(m_currentOperation).errorStrings.size();i++)
        {
            if(str.indexOf(m_operList->at(m_currentOperation).errorStrings.at(i))>=0)
            {
                errorFound=true;
                emit Error(m_operList->at(m_currentOperation).errorMsg);
                break;
            }
        }

        //parsing answer
        if(!errorFound)
        {
            for(int i=0;i<recParam->size();i++)
            {
                int start_index=ReplyStr.indexOf(recParam->at(i).key);
                if(start_index>=0)
                {
                    start_index+=recParam->at(i).key.length();
                    int last_index=-1;
                    if(recParam->at(i).value=="") last_index=ReplyStr.indexOf("\"",start_index);
                    else last_index=ReplyStr.indexOf(recParam->at(i).value,start_index);
                    if(last_index>=0)
                    {
                        (*m_operList)[m_currentOperation].ReceiveParamenters[i].value=(QString)ReplyStr.mid(start_index,last_index-start_index);
                        m_hash[recParam->at(i).hash_key]=m_operList->at(m_currentOperation).ReceiveParamenters.at(i).value;
                        valid_results++;
                    }
                }
            }
            if(valid_results>0)
                //finishedOper();
                emit OperFinished();
            else if (recParam->size()>0)
                emit Error("Error. No valid results");
            else
                //finishedOper();
                emit OperFinished();
        }
    }
    else if(m_operList->at(m_currentOperation).answerType==JSONAnswer)
    {
        QJsonDocument *jsonAnswer=new QJsonDocument;
        *jsonAnswer= QJsonDocument::fromJson(bytes) ;
        QJsonObject jsonObj=jsonAnswer->object();


        for(int i=0;i<m_operList->at(m_currentOperation).errorStrings.size();i++)
        {
            if(jsonObj.value(m_operList->at(m_currentOperation).errorStrings.at(i)).isString())
            {
                errorFound=true;
                emit Error(m_operList->at(m_currentOperation).errorMsg);
                break;
            }
        }

        if(!errorFound)
        {
            for(int i=0;i<m_operList->at(m_currentOperation).ReceiveParamenters.size();i++)
            {
                if(jsonObj.value(recParam->at(i).key).isString())
                {
                    m_hash[recParam->at(i).hash_key]=jsonObj.value(recParam->at(i).key).toString();
                    valid_results++;
                }
            }
            if(valid_results>0)
                //finishedOper();
                emit OperFinished();
            else if (recParam->size()>0)
                emit Error("Error. No valid JSON results");
            else
                //finishedOper();
                emit OperFinished();
        }
    }
}


//QString ServiceProvider::TakeAddress(QString adress_string)
//{
////    QString("<<redirect_to>>")+
////    QString("?return_to=https://secure.privatbank.ua/ru/company/kyivstar/request/")+
////    QString("<<token>>")

//    int index=adress_string.indexOf("<<");
//    int index2=adress_string.indexOf(">>");
//    if(!((index>=0)&&(index2>=0))) return adress_string;

//    QString result;
//    QString postfix;
//    int offset=0;
//    while((index>=0)&&(index2>=0))
//    {
//        QString prefix=adress_string.left(index);
//        postfix=adress_string.right(adress_string.size()-index2-2);
//        QString key=adress_string.mid(index+2,index2-index);
//        QString value=m_hash[key];
//        result+=prefix+(value);
//        offset+=index2+2;
//        index=adress_string.indexOf("<<",offset);
//        index2=adress_string.indexOf(">>",offset);
//    }
//    result+=postfix;
//    return result;
//}

QString ServiceProvider::TakeAddress(QString adress_string)
{
    int index=adress_string.indexOf("<<");
    int index2=adress_string.indexOf(">>");
    if(!((index>=0)&&(index2>=0))) return adress_string;

    QString copy_str=adress_string;
    QList<QPair<QString, QString> > values;
    QString key;
    int offset=0;

    while((index>=0)&&(index2>=0))
    {
        key=adress_string.mid(index+2,index2-index-2);
        values.append(QPair<QString, QString>("<<"+key+">>",m_hash[key]));
        offset+=index2+2;
        index=adress_string.indexOf("<<",offset);
        index2=adress_string.indexOf(">>",offset);
    }

    for(int i=0;i<values.size();i++)
        copy_str.replace(values.at(i).first, values.at(i).second);

    qDebug()<<"Address string:"<<copy_str;
    if(m_currentOperation==8)
        qDebug()<<"8th";
    return copy_str;
}
